/** Definition of the AssemblerMIPS class.
 * @file 
 * @author Jeremy Schultz
 */

#ifndef	__ASSEMBLERMIPS_H_
#define	__ASSEMBLERMIPS_H_

#include <iostream>
#include <fstream>
#include <map>
#include <sstream>

using namespace std;

/** Describes a AssemblerMIPS for the PL lanaguage.
 * Notes:
 *  MIPS use a stack the grows down, that means to add to the stack
 *   you need decreament the address.
 *
 * There was no need to keep track of address labels, since MIPS supports labels.
 * 
 * In the manual it stated that the minium stack frame is 8 words (32 bytes).
 *    The PL implementation only uses 3 words, thus there is 5 words of
 *    wasted space. 
 *    It should be possible to use this left over space for local variables.
 *     This would require some extra code to remember how much of the extra space
 *     was been used and if we need to start allocating new space on the stack
 *     for more local variables.
 *
 * Other optimization that can be done, remove reduntant code or useless code.
 *  Such as not outputing the code in VARAIABLE to find the base pointer if level
 *   is 0. 
 */
class AssemblerMIPS	{
	private:
		istream *in;			/**< Input stream */
		ostream *out;			/**< Output stream */
		map<int,int> varSize;			/**< Keep track of variable sizes  */

		/** Create a uniqueLabel.
		 * Creates a label from a string by adding a unique ID to the end.
		 * @param label  The string to add an unique ID to
		 * @return the unique label.
		 */
		string uniqueLabel(string label); 

	public:

		/** Constuctor.
		 * @param _in  The input stream
		 * @param _out  The input stream
		 */
		AssemblerMIPS(istream &_in, ostream &_out);

		/** First Pass
		 * The first pass creates a look up table for the variable sizes
		 */
		void firstPass();

		/** Second Pass
		 * Outputs the MIPS code.
		 * Each section of the code is fully documented using inline comments.
		 */
		void secondPass();

};
#endif

